abstract class Component {
    children: Component[];
    props: any;

    protected constructor(props: any, children?: Component[]) {
        this.props = props;
        this.children = children;
    }

    abstract operate(): void;
}

class Composite extends Component {
    constructor(props: any, children: Component[]) {
        super(props, children);
    }
    operate() {
        console.log('this is composite, props: ', this.props);
        this.children.forEach((child) => {
            child.operate();
        });
    }
}

class Leaf extends Component {
    constructor(props: any) {
        super(props);
    }
    operate() {
        console.log('this is leaf, props: ', this.props);
    }
}

const element = new Composite('a', [new Composite('b', [new Leaf('d'), new Leaf('e')]), new Composite('c', [new Leaf('f'), new Leaf('g')])]);
element.operate();